package com.py.framework.service.impl;

import com.py.framework.common.Constants;
import com.py.framework.core.exception.ServiceException;
import com.py.framework.core.helper.JWTHelper;
import com.py.framework.core.utils.DateUtils;
import com.py.framework.core.utils.SerializingUtil;
import com.py.framework.dao.IntegrationMenuResourceDao;
import com.py.framework.entity.MenuEntity;
import com.py.framework.entity.RoleEntity;
import com.py.framework.entity.UserEntity;
import com.py.framework.filter.IntegrationMenuCacheHelper;
import com.py.framework.service.AuthenticationService;
import com.py.framework.service.IntegrationMenuResourceService;
import com.py.framework.service.RoleService;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 菜单资源Service实现
 *
 * @author Leegern
 * @date 2018年4月23日
 */
@Service
public class IntegrationMenuResourceServiceImpl implements IntegrationMenuResourceService {

    @Autowired
    private IntegrationMenuResourceDao integrationMenuResourceDao;

    @Autowired
    private RoleService roleService;

    @Autowired
    private AuthenticationService authenticationService;

    /*
     * (non-Javadoc)
     * @see com.py.framework.service.MenuResourceService#queryMenuResourceForPage(java.util.Map)
     */
    @Override
    public List<MenuEntity> queryMenuResourceForPage(Map<String, Object> params) {
        return integrationMenuResourceDao.queryMenuResourceForPage(params);
    }

    /*
     * (non-Javadoc)
     * @see com.py.framework.service.MenuResourceService#getMenuResourceByParentId(java.lang.String)
     */
    @Override
    public List<MenuEntity> getMenuResourceByParentId(String parentId) {
        return integrationMenuResourceDao.getMenuResourceByParentId(parentId);
    }

    /*
     * (non-Javadoc)
     * @see com.py.framework.service.MenuResourceService#getMenuResourceByMenuType(int)
     */
    @Override
    public List<MenuEntity> getMenuResourceByMenuType(int menuType) {
        return integrationMenuResourceDao.getMenuResourceByMenuType(menuType);
    }

    /*
     * (non-Javadoc)
     * @see com.py.framework.service.MenuResourceService#findOneMenuResource(long)
     */
    @Override
    public MenuEntity findOneMenuResource(long id) {
        if (id > Constants.NUMBER_ZERO) {
            return integrationMenuResourceDao.findOneMenuResource(id);
        }
        return null;
    }

    @Override
    public MenuEntity getMenuNameByLinkURL(String linkUrl) {
        if (null != linkUrl && linkUrl.length() > Constants.NUMBER_ZERO) {
            return integrationMenuResourceDao.getMenuNameByLinkURL(linkUrl);
        }
        return null;
    }

    /*
     * (non-Javadoc)
     * @see com.py.framework.service.MenuResourceService#addMenuResourceInfo(com.py.framework.entity.MenuEntity)
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public int addMenuResourceInfo(MenuEntity entity) {
        if (null != entity) {
            if (entity.getParentId() > Constants.NUMBER_ZERO) {
                MenuEntity menu = this.findOneMenuResource(entity.getParentId());
                if (null != menu && StringUtils.isNotBlank(menu.getAllParentId())) {
                    entity.setAllParentId(menu.getAllParentId() + "," + entity.getParentId());
                } else {
                    entity.setAllParentId(String.valueOf(entity.getParentId()));
                }
            }
            entity.setCreateTime(new Timestamp(System.currentTimeMillis()));
            entity.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            entity.setDelFlag(Constants.NUMBER_ONE);
            return integrationMenuResourceDao.addMenuResourceInfo(entity);
        }
        return 0;
    }

    /*
     * (non-Javadoc)
     * @see com.py.framework.service.MenuResourceService#updateMenuResource(com.py.framework.entity.MenuEntity)
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public int updateMenuResource(MenuEntity entity) {
        entity.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        return integrationMenuResourceDao.updateMenuResource(entity);
    }

    /*
     * (non-Javadoc)
     * @see com.py.framework.service.MenuResourceService#batchDelMenuResource(java.util.List)
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public int batchDelMenuResource(List<Long> ids) {
        int flag = 0;
        if (!CollectionUtils.isEmpty(ids)) {
            Map<String, Object> params = new HashMap<String, Object>();
            List<MenuEntity> datas = null;
            for (Long id : ids) {
                datas = integrationMenuResourceDao.getMenuResourceByParentId(String.valueOf(id));
                if (!CollectionUtils.isEmpty(datas)) {
                    throw new ServiceException("存在子节点，删除失败！");
                }
            }
            params.put("updateTime", new Timestamp(DateUtils.getCurrentDateTime().getTime()));
            params.put("ids", ids);
            flag = integrationMenuResourceDao.batchDelMenuResource(params);
            // 删除角色菜单资源信息
            for (Long menuId : ids) {
                params.clear();
                params.put("menuId", menuId);
                roleService.delRoleMenuRelate(params);
            }
        }
        return flag;
    }

    /*
     * (non-Javadoc)
     * @see com.py.framework.service.MenuResourceService#getUserMenuResources(long)
     */
    @Override
    public List<MenuEntity> getUserMenuResources(long userId) {
        if (userId > Constants.NUMBER_ZERO) {
            return integrationMenuResourceDao.getUserMenuResources(userId);
        }
        return null;
    }

    /*
     * (non-Javadoc)
	 *
	 * @see com.py.framework.service.AuthenticationService#
	 * getCurrentUserMenuResources(java.lang.String)
	 */
    @SuppressWarnings("unchecked")
    @Override
    public List<MenuEntity> getCurrentUserMenuResources(String jdToken) throws Exception {
        List<MenuEntity> menus = null;
        long userId = 0L;
        if (StringUtils.isNotBlank(jdToken)) {
            UserEntity user = authenticationService.getCurrentUserInfo(jdToken);
            // 超级管理员展示所有菜单
            if (null != user && user.getUserType() == 3) {
                menus = integrationMenuResourceDao.getMenuResourceByMenuType(Constants.NUMBER_ZERO);
            } else {
                byte[] bts = IntegrationMenuCacheHelper.getUserMenuFromCache(SerializingUtil.serialize(jdToken));
                if (null != bts && bts.length > Constants.NUMBER_ZERO) {
                    menus = (List<MenuEntity>) SerializingUtil.deserialize(bts);
                } else {
                    userId = this.pickUserId(jdToken);
                    if (userId > Constants.NUMBER_ZERO) {
                        menus = integrationMenuResourceDao.getUserMenuResources(integrationMenuResourceDao.selectUserRoleId(userId));
                        if (!CollectionUtils.isEmpty(menus)) {
                            // 缓存用户菜单资源
                            IntegrationMenuCacheHelper.putUserMenuCache(SerializingUtil.serialize(jdToken),
                                    SerializingUtil.serialize(menus));
                            // 缓存用户资源数据
                            IntegrationMenuCacheHelper.putUserResourcesCache(SerializingUtil.serialize(jdToken),
                                    SerializingUtil.serialize(this.populateResources(menus)));
                        }
                    }
                }
            }
        }
        return menus;
    }

    @Override
    public List<RoleEntity> getIntegrationMenuRelate(long roleId) {
        if (roleId > Constants.NUMBER_ZERO) {
            return integrationMenuResourceDao.getIntegrationMenuRelate(roleId);
        }
        return null;
    }

    @Override
    public int modifyRegionMenuRelate(List<RoleEntity> datas) {
        if (! CollectionUtils.isEmpty(datas)) {
            RoleEntity role = datas.get(0);
            if (role.getId() > Constants.NUMBER_ZERO) {
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("roleId", role.getId());
                if(datas.size()==1) {
                    integrationMenuResourceDao.delRegionMenuRelate(params);
                }else {
                    integrationMenuResourceDao.delRegionMenuRelate(params);
                    return integrationMenuResourceDao.addRegionMenuRelate(datas);
                }
            }
        }
        return 0;
    }

    /**
     * 解密用户Id
     *
     * @param jdToken 令牌
     * @return
     * @throws Exception
     */
    private long pickUserId(String jdToken) throws Exception {
        Claims claims = JWTHelper.parseJWT(jdToken);
        long userId = 0L;
        if (null != claims && StringUtils.isNotBlank(claims.getSubject())) {
            userId = Long.parseLong(claims.getId());
        }
        return userId;
    }

    /**
     * 组装资源
     *
     * @param menus 菜单集合
     * @return
     */
    private Map<String, String> populateResources(List<MenuEntity> menus) {
        Map<String, String> result = new HashMap<>();
        if (!CollectionUtils.isEmpty(menus)) {
            for (MenuEntity menuEntity : menus) {
                if (StringUtils.isNotBlank(menuEntity.getLinkUrl())) {
                    result.put(menuEntity.getLinkUrl(), menuEntity.getLinkUrl());
                }
            }
        }
        return result;
    }
    
    public int isResourceInfo(long roleId,String url){
    	return integrationMenuResourceDao.isResourceInfo(roleId, url);
    }
}